package app.objectstoragedemo.service;


import app.objectstoragedemo.Pojo.CopyUtils.CopyFileUtils;
import app.objectstoragedemo.Pojo.Exception.BusinessException;
import app.objectstoragedemo.Pojo.Exception.StatusCode;
import app.objectstoragedemo.Pojo.FinalClass.AppConfig;
import app.objectstoragedemo.Pojo.Mapper.FileStorage;
import app.objectstoragedemo.Pojo.Vo.FileLimitVo;
import app.objectstoragedemo.Pojo.Vo.UploadFileVo;
import app.objectstoragedemo.mapper.FileMapper;
import app.objectstoragedemo.service.impl.FileServiceInterface;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.activation.MimetypesFileTypeMap;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
@RequiredArgsConstructor
@Slf4j
public class FileService extends ServiceImpl<FileMapper, FileStorage> implements FileServiceInterface {

    private final FileMapper fileMapper;
    private final AppConfig appConfig;

    @Override
    public UploadFileVo uploadFile(MultipartFile file) {

        // 获取上传目录
        Path uploadPath = Path.of(new File(appConfig.getUploadPath()).getAbsolutePath());
        //获取原始文件名 - 1.jpg  123.0.0.jpg
        String originalFilename = file.getOriginalFilename();
        //构造唯一的文件名 (不能重复) - uuid(通用唯一识别码) de49685b-61c0-4b11-80fa-c71e95924018
        //uuid(通用唯一识别码)+ "_"+原始文件名+原始文件扩展名=组合成新的文件名 de49685b-61c0-4b11-80fa-c71e95924018_1.jpg
        UUID uuid = UUID.randomUUID();
        //  构造唯一的文件名
        //  String newFileName = uuid + "_" + originalFilename;
        String newFileName = uuid.toString();
        // 保存文件到上传目录
        log.info("文件上传位置 {}", uploadPath.resolve(newFileName));
        Path filePath = uploadPath.resolve(newFileName);

        // 保存文件到上传目录
        try {
            file.transferTo(filePath.toFile());
        } catch (IOException e) {
            throw new BusinessException(StatusCode.ERROR_CODE, "文件上传失败: " + e.getMessage());
        }

        //添加到数据库
        FileStorage fileStorage = FileStorage.builder().uuid(uuid.toString()).name(originalFilename).type(new MimetypesFileTypeMap().getContentType(originalFilename)).path(filePath.toString()).build();


        if (fileMapper.insert(fileStorage) <= 0) {
            throw new BusinessException(StatusCode.ERROR_CODE, "文件上传失败");
        }

        //返回数据
        return CopyFileUtils.FileStorageToUploadFileVo(fileStorage);
    }

    @Override
    public FileLimitVo InquireFile(int Current, int limit) {
        // 创建 分页查询 类 第 page 页，每页limit 条数据。
        Page<FileStorage> page1 = new Page<>(Current, limit);
        // 使用 分页查询
        Page<FileStorage> productPage = fileMapper.selectPage(page1, null);
        // 获取查询结果
        List<FileStorage> fileStorages = productPage.getRecords();

        ArrayList<UploadFileVo> uploadFileVos = new ArrayList<>();

        fileStorages.forEach(fileStorage -> uploadFileVos.add(CopyFileUtils.FileStorageToUploadFileVo(fileStorage)));


        //productPage.getPages() 总页码数
        //productPage.getSize() 每页显示的商品数量
        //productPage.getCurrent() 当前页码
        return new FileLimitVo(uploadFileVos, productPage.getPages(), productPage.getCurrent(), productPage.getSize());
    }


    @Override
    public FileStorage selectByUuid(String uuid) {
        LambdaQueryWrapper<FileStorage> last = new LambdaQueryWrapper<FileStorage>().eq(FileStorage::getUuid, uuid).last("LIMIT 1");

        return fileMapper.selectOne(last);
    }


    @Override
    public int deleteFile(String uuid) {
        LambdaQueryWrapper<FileStorage> wrapper = new LambdaQueryWrapper<FileStorage>().eq(FileStorage::getUuid, uuid);
        FileStorage fileStorage = fileMapper.selectOne(wrapper);
        if (fileStorage.getPath() != null) {
            Path path = Path.of(fileStorage.getPath());
            if (path.toFile().exists()) {
                log.info(path.toFile().delete() ? "文件删除成功" : "文件删除失败");
            }
        }

        return fileMapper.delete(wrapper);
    }
}
